package view.inventory;

import java.awt.Color;
import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellRenderer;
import main.ServicesList;
import model.inventory.Item;
import model.inventory.ItemSupplier;
import model.publics.Supplier;
import org.apache.log4j.Logger;
import utility.Constants;
import utility.NameValueList;
import utility.com.CheckboxTableRenderer;
import utility.com.InputValidation;
import view.lookup.LookupSimpleFrm;


public class ItemSupplierFrm extends javax.swing.JFrame {

    private static final int COL_NO  = 0;
    private static final int COL_KODE  = 1;
    private static final int COL_NAMA  = 2;
    private static final int COL_AKTIF = 3;
    
  //  final JCheckBox aktiveCE = new JCheckBox();
    
    private ItemSupplierTM itemTM;
    private ItemSupplier itemSupplier;
    private List<ItemSupplier> itemSuppliers;
    
    private static Logger log = Logger.getLogger(ItemSupplierFrm.class);
    private Object oldValue, newValue;
    
    public ItemSupplierFrm() {
        initComponents();
        initComponentsRules();
    }

    public void execute(boolean withVisible, int id) {
        setLocationRelativeTo(null);
        initForm();
        if (withVisible) { setVisible(true); }
    }
    
    private void initComponentsRules() {
        btnNew.registerKeyboardAction(btnNew.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, false)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, false), JComponent.WHEN_FOCUSED);
 
        btnNew.registerKeyboardAction(btnNew.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, true)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, true), JComponent.WHEN_FOCUSED);
        
        btnDelete.registerKeyboardAction(btnDelete.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, false)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, false), JComponent.WHEN_FOCUSED);

        btnDelete.registerKeyboardAction(btnDelete.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, true)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, true), JComponent.WHEN_FOCUSED);

        btnSave.registerKeyboardAction(btnSave.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, false)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, false), JComponent.WHEN_FOCUSED);
 
        btnSave.registerKeyboardAction(btnSave.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, true)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, true), JComponent.WHEN_FOCUSED);
        
        txtPlu.addKeyListener(new ActionKeyListener());
        txtSuplier.addKeyListener(new ActionKeyListener());
        
        txtPlu.addFocusListener(new ActionFocusGained());
        txtSuplier.addFocusListener(new ActionFocusGained());
        grid.getSelectionModel().addListSelectionListener(new GridSelectionListener());
    }
    
    private void initGrid() {
        itemTM = new ItemSupplierTM(itemSuppliers);
        grid.setModel(itemTM);

        grid.getColumnModel().getColumn(COL_AKTIF).setCellRenderer(new CheckboxTableRenderer());
        grid.getColumnModel().getColumn(COL_NO).setMaxWidth(30);
        grid.getColumnModel().getColumn(COL_NO).setMinWidth(30);
        grid.getColumnModel().getColumn(COL_NO).setPreferredWidth(30);
        
        grid.getColumnModel().getColumn(COL_AKTIF).setMaxWidth(50);
        grid.getColumnModel().getColumn(COL_AKTIF).setMinWidth(50);
        grid.getColumnModel().getColumn(COL_AKTIF).setPreferredWidth(50);
        
        grid.getColumnModel().getColumn(COL_KODE).setMaxWidth(90);
        grid.getColumnModel().getColumn(COL_KODE).setMinWidth(90);
        grid.getColumnModel().getColumn(COL_KODE).setPreferredWidth(90);
        
        //look style
        final TableCellRenderer header = grid.getTableHeader().getDefaultRenderer();
        grid.getTableHeader().setDefaultRenderer(new TableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                JLabel lbl = (JLabel) header.getTableCellRendererComponent(table, 
                      value, isSelected, hasFocus, row, column);
                lbl.setBorder(BorderFactory.createEmptyBorder(5,1,5,1));   
   
                switch (column) {
                    case COL_NO: lbl.setHorizontalAlignment(SwingConstants.RIGHT); break;
                    case COL_AKTIF: lbl.setHorizontalAlignment(SwingConstants.CENTER); break;
                    default: lbl.setHorizontalAlignment(SwingConstants.LEFT); break;   
                }
                lbl.setForeground(Color.WHITE);
                lbl.setBackground(Color.DARK_GRAY);
                return lbl;
            }
        });
        grid.setGridColor(Color.LIGHT_GRAY);
    }
    
    private void initForm() {
        txtItemName.setText("");
        txtPlu.setText("");
        txtSuplier.setText("");
        txtSuplierName.setText("");
        chkAktif.setSelected(false);
        itemSupplier = new ItemSupplier();
        itemSuppliers = new ArrayList<>();
        initGrid();
    }

    private void saveData() {
        itemSupplier.setAktive(chkAktif.isSelected());
        boolean saved = false;
        try{
            saved = ServicesList.getItemSupplierService().save(itemSupplier);
            loadData();
        } catch(Exception ex){
            log.error(ex);
            JOptionPane.showMessageDialog(this, "Data gagal disimpan.", "Error",JOptionPane.ERROR_MESSAGE);
        }
        
        initButtonState(!saved);
    }
    
    private void validasi() {
        
        if (InputValidation.isValid(txtPlu, itemSupplier.getId().getItemId() > 0, "Barang belum diisi.")) {
        if (InputValidation.isValid(txtSuplier, itemSupplier.getId().getSupplierId() > 0, "Supplier belum diisi.")) {
            
            Boolean notExist = true;
            if (chkAktif.isSelected()) {
                Map<NameValueList, Object> params = new HashMap<>();
                params.put(new NameValueList("itemSupplier.id.itemId", Constants.OPERATOR_EQUAL), itemSupplier.getId().getItemId()); 
                params.put(new NameValueList("itemSupplier.id.supplierId", Constants.OPERATOR_NOT_EQUAL), itemSupplier.getId().getSupplierId()); 
                params.put(new NameValueList("itemSupplier.aktive", Constants.OPERATOR_EQUAL), true); 

                notExist = !ServicesList.getItemSupplierService().isExist(params); 
            }
            
            if (InputValidation.isValid(txtPlu, notExist, "Sudah ada supplier yg aktif.")) {
                saveData();
            }
        }}
    }
    
    private void loadData() {
        if(itemSupplier!=null) {
            Map<NameValueList, Object> params = new HashMap<>();
            params.put(new NameValueList("itemSupplier.id.itemId", Constants.OPERATOR_EQUAL), itemSupplier.getId().getItemId()); 
            params.put(new NameValueList(null, Constants.OPERATOR_ORDERBY), "itemSupplier.supplier.nama"); 
            itemSuppliers = ServicesList.getItemSupplierService().getAll(params);
            initGrid();
        }
    }
    
     private void deleteRow () {
        int rowCount = grid.getRowCount();
        int row = grid.getSelectedRow();
        
        ItemSupplier deletedData= itemSuppliers.get(row);
        boolean saved = ServicesList.getItemSupplierService().delete(deletedData);
        if (!saved) {
            JOptionPane.showMessageDialog(this, "Data gagal dihapus.", "Error",JOptionPane.ERROR_MESSAGE);
        
        }else {
            itemSuppliers.remove(row);
            itemTM.fireTableRowsDeleted(row, row);
        }
    }
    
    private void lookupMaster(int purpose, String param) {
        Object object = new LookupSimpleFrm().execute(purpose, param); 
        if (object != null) { setMaster(purpose, object); }
    }
    
    private void setMaster(int purpose, Object object) {
        if (object != null) {
            switch (purpose) {
                case Constants.LOOKUP_ITEM:
                    Item item = ((Item) object);
                    txtPlu.setText(item.getPlu());
                    txtItemName.setText(item.getNama());
                    itemSupplier.getId().setItemId(item.getId());
                    loadData();
                    txtSuplier.requestFocus();
                    break;
                    
                case Constants.LOOKUP_SUPPLIER:
                    Supplier supplier = (Supplier) object;
                    txtSuplier.setText(supplier.getKode());
                    txtSuplierName.setText(supplier.getNama());
                    itemSupplier.getId().setSupplierId(supplier.getId());
                    itemSupplier.setSupplier(supplier);
                    
                    //loadData();
                    break;
                    
                default: break;    
            }
        }
    }
    
    private void getMaster(int purpose, String kode) {
         switch (purpose) {
           case Constants.LOOKUP_ITEM:
               Item item = ServicesList.getItemService().getItem(kode);
               if (item != null) {setMaster(purpose, item); }
               else { lookupMaster(purpose, txtPlu.getText()); }
               break;
               
           case Constants.LOOKUP_SUPPLIER:
               
               Supplier supplier = ServicesList.getSupplierService().getSupplier(kode);
               if (supplier != null) {setMaster(purpose, supplier); }
               else { lookupMaster(purpose, txtSuplier.getText()); }
               break;
               
           default: break;    
        }
    }
    
    private void initButtonState(boolean status) {
        btnSave.setEnabled(status);
    }
            
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jToolBar1 = new javax.swing.JToolBar();
        btnNew = new javax.swing.JButton();
        btnSave = new javax.swing.JButton();
        btnDelete = new javax.swing.JButton();
        txtPlu = new javax.swing.JTextField();
        txtSuplier = new javax.swing.JTextField();
        txtItemName = new javax.swing.JTextField();
        txtSuplierName = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        grid = new javax.swing.JTable();
        chkAktif = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jToolBar1.setFloatable(false);
        jToolBar1.setRollover(true);
        jToolBar1.setMaximumSize(new java.awt.Dimension(32767, 20));
        jToolBar1.setSize(this.getWidth(), 50);

        btnNew.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edit_add.png"))); // NOI18N
        btnNew.setText("Tambah");
        btnNew.setFocusable(false);
        btnNew.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnNew.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNewActionPerformed(evt);
            }
        });
        jToolBar1.add(btnNew);

        btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edit.png"))); // NOI18N
        btnSave.setText("Save");
        btnSave.setFocusable(false);
        btnSave.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnSave.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });
        jToolBar1.add(btnSave);

        btnDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edit_remove.png"))); // NOI18N
        btnDelete.setText("Delete");
        btnDelete.setFocusable(false);
        btnDelete.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnDelete.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnDeleteActionPerformed(evt);
            }
        });
        jToolBar1.add(btnDelete);

        txtPlu.setName("txtPlu"); // NOI18N

        txtSuplier.setName("txtSuplier"); // NOI18N

        txtItemName.setEditable(false);
        txtItemName.setFocusable(false);
        txtItemName.setName("txtItemName"); // NOI18N

        txtSuplierName.setEditable(false);
        txtSuplierName.setFocusable(false);
        txtSuplierName.setName("txtSuplierName"); // NOI18N

        jLabel1.setText("PLU :");

        jLabel2.setText("Supplier :");

        grid.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {},
                {},
                {},
                {}
            },
            new String [] {

            }
        ));
        grid.setName("grid"); // NOI18N
        jScrollPane1.setViewportView(grid);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 581, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel2))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(txtPlu, javax.swing.GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE)
                            .addComponent(txtSuplier))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(txtItemName)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(chkAktif)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(txtSuplierName))))
                    .addComponent(jScrollPane1))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtPlu, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtItemName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtSuplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtSuplierName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2)
                    .addComponent(chkAktif))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 264, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewActionPerformed
        initForm();
        txtPlu.requestFocus();
    }//GEN-LAST:event_btnNewActionPerformed

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
        validasi();
    }//GEN-LAST:event_btnSaveActionPerformed

    private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeleteActionPerformed
        deleteRow();
    }//GEN-LAST:event_btnDeleteActionPerformed

    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnDelete;
    private javax.swing.JButton btnNew;
    private javax.swing.JButton btnSave;
    private javax.swing.JCheckBox chkAktif;
    private javax.swing.JTable grid;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JTextField txtItemName;
    private javax.swing.JTextField txtPlu;
    private javax.swing.JTextField txtSuplier;
    private javax.swing.JTextField txtSuplierName;
    // End of variables declaration//GEN-END:variables

    @Override
    public void setVisible(boolean value) {
        super.setVisible(value);
        txtPlu.requestFocusInWindow();
    }
    
    private void moveNext() {
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.focusNextComponent();
    }
    
    class ActionKeyListener implements KeyListener {
        @Override public void keyTyped(KeyEvent e) {} 
        @Override public void keyReleased(KeyEvent e) {}
        @Override public void keyPressed(KeyEvent e) {
            switch (e.getKeyCode()) { 
                case KeyEvent.VK_F2: 
                    switch(e.getComponent().getName()) {
                        case "txtPlu": lookupMaster(Constants.LOOKUP_ITEM, txtPlu.getText()); break;
                        case "txtSuplier": lookupMaster(Constants.LOOKUP_SUPPLIER, txtSuplier.getText()); break;
                    };
                break;  
                
                case KeyEvent.VK_ENTER: 
                    switch(e.getComponent().getName()) {
                        case "txtPlu": 
                            newValue = txtPlu.getText();
                            if (!newValue.equals(oldValue)) { getMaster(Constants.LOOKUP_ITEM, txtPlu.getText()); }
                            else {moveNext();}
                            break;
                            
                        case "txtSuplier": 
                            newValue = txtSuplier.getText();
                            if (!newValue.equals(oldValue)) { getMaster(Constants.LOOKUP_SUPPLIER, txtSuplier.getText()); }
                            else {moveNext();}
                            break;
                                
                       default: moveNext(); break;
                    };
                break;      
            }
        }
    }
    
    class ActionFocusGained implements FocusListener {
        @Override public void focusGained(FocusEvent e) { 
            Component componen = (Component) e.getSource(); 
            if (componen instanceof JTextField) { oldValue = ((JTextField) componen).getText();
            }else if (componen instanceof JCheckBox) { oldValue = ((JCheckBox) componen).isSelected(); }
        }
        
        @Override public void focusLost(FocusEvent e) {
            Component componen = (Component) e.getSource(); 
            if (componen instanceof JTextField) { newValue = ((JTextField) componen).getText();
            }else if (componen instanceof JCheckBox) { newValue = ((JCheckBox) componen).isSelected(); }
            
            if (!newValue.equals(oldValue)) { initButtonState(true); }
        }
    }
    
//    class GridActionListener implements ActionListener {
//        @Override
//        public void actionPerformed(ActionEvent e) {
//            if ("JCheckBox".equals(e.getSource().getClass().getSimpleName())) {
//            }    
//        }
//    }
    
    private class GridSelectionListener implements ListSelectionListener{
        @Override public void valueChanged(ListSelectionEvent e) {
            if(grid.getSelectedRow()>=0){ 
                itemSupplier = itemSuppliers.get(grid.getSelectedRow()); 
                if (itemSupplier!=null) {
                    txtPlu.setText(itemSupplier.getItem().getPlu());
                    txtItemName.setText(itemSupplier.getItem().getNama());
                    txtSuplier.setText(itemSupplier.getSupplier().getKode());
                    txtSuplierName.setText(itemSupplier.getSupplier().getNama());
                    chkAktif.setSelected(itemSupplier.getAktive());
                    initButtonState(true);
                }
            }
        }
    }
    
    private void setTableLookStyle() {
        
    }
}
